(function() {
if (document.readyState !== 'loading') {
    init();
} else {
    document.addEventListener('DOMContentLoaded', init);
}

function init() {
    const tabId = 'user_manage';
    const container = document.querySelector(`[data-tab-id="${tabId}"]`);
    const $container = $(container);
    // const API_BASE = window.location.origin;
    const url = `${window.location.origin}/acc/rbac/user/manage/`;
    const tableLabel = '.user_manage_son'

    // 直接解析原生JSON
    const ownID = JSON.parse(container.querySelector('#ownIDData').textContent);

    let ownUser_is_superuser = JSON.parse(container.querySelector('#ownUser_is_superuserData').textContent);
    let ownUser = JSON.parse(container.querySelector('#ownUserData').textContent);
    let ownUser_permissions = JSON.parse(container.querySelector('#ownUser_permissionsData').textContent);
    let users = JSON.parse(container.querySelector('#usersData').textContent);
    let groups = JSON.parse(container.querySelector('#groupsData').textContent);
    let userId = ''

    const headers = {
        'Authorization': 'Bearer ' + localStorage.getItem('access'),
        'Content-Type': 'application/json',
    }

    // 检查是否有权限:
    let isPassword = ownUser_is_superuser ? true : ownUser_permissions.includes('修改密码');
    let isEditUser = ownUser_is_superuser ? true : ownUser_permissions.includes('编辑用户');
    let isDeleteUser = ownUser_is_superuser ? true : ownUser_permissions.includes('删除用户');
    let isNewUser = ownUser_is_superuser ? true : ownUser_permissions.includes('新增用户');


    // 在所有Tab页面创建相同的频道
    const bc = new BroadcastChannel('data_update_channel');


    // 0.监听其他Tab的消息
    bc.addEventListener('message', (event) => {
      if (event.data.type === 'data_updated') {
         updateLocalData(event.data.payload);
     }
     });

    // 监听click事件
    container.addEventListener('click', function (e) {
        // 1. 新增用户功能
        if (e.target.closest('.addNewRow')) {
            if(!isNewUser){showToast('您没有新增用户的权限', 'warning'); return;}
            addNewRow()
        }

        // 2.行编辑功能
        if (e.target.closest('.edit-btn')) {
            if(!isEditUser){showToast('您没有编辑用户的权限', 'warning'); return;}
            enableEdit(e.target.closest('tr'))
        }

        // 3.修改密码
        if (e.target.closest('.reset-pwd-btn')) {
            if(!isPassword){showToast('您没有修改密码的权限', 'warning'); return; }
            // 动态创建模态框实例
            const modalEl = document.getElementById('passwordResetModal');
            const modal = bootstrap.Modal.getInstance(modalEl) || new bootstrap.Modal(modalEl);

            if (!isPassword) {
                showToast('您没有修改密码的权限', 'warning');
            } else {
                // 手动触发模态框显示
                modal.show();
                // 行高亮逻辑
                const row = e.target.closest('tr');
                userId = row.dataset.id;
                row.classList.add('table-danger');
                modalEl.currentHighlightRow = row;
            }
        }

        // 4.送短信验证码
        if(e.target.closest('.sendSmsCode')){ sendSmsCode().then() }

        // 5.密码明文与密文
        if(e.target.closest('.togglePassword')){
            const element = e.target.closest('.togglePassword');
            togglePassword(element.dataset.fieldId, element)
        }

        // 6.删除操作
        if (e.target.closest('.delete-btn')) {
            if(!isDeleteUser){showToast('您没有删除的权限', 'warning'); return;}
            const row = e.target.closest('tr');
            // 高亮目标行
            row.classList.add('table-danger')
            const userId = e.target.closest('tr').dataset.id;
            const modal = new bootstrap.Modal('#deleteConfirmModal');
            modal.show();
            // 监听删除模态框的id='confirmDelete'
            container.querySelector('#confirmDelete').onclick = () => {
                fetch(`/acc/users/${userId}/`, {method: 'DELETE', headers: headers,})
                    .then(response => {
                        if (response.ok) {
                            e.target.closest('tr').remove();
                            modal.hide();

                            // 删除本地users里的用户
                            users = users.filter(user => parseInt(user.id) !== parseInt(userId));
                            // 发送数据给其他tab页同步用:(要发送删除的用户)
                            bc.postMessage({
                                type: 'data_updated',
                                payload: {"user_delete_id": userId}
                            });
                        }else{
                            modal.hide();
                            showToast('删除失败!', 'error')
                        }
                    })
            };
            // 监听模态框关闭事件（取消操作,取消高亮）
            modal._element.addEventListener('hidden.bs.modal', () => {
                row.classList.remove('table-danger');
            })
        }

        // 7.保存新建
        if (e.target.closest('.save-new')) {
            const row = e.target.closest('tr');
            const data = collectRowData(row);
            fetch('/acc/users/', {
                method: 'POST',
                headers: headers,
                body: JSON.stringify(data)
            })
                .then(response => {
                    if (!response.ok) {
                        // 尝试解析错误信息（后端需返回 JSON 格式错误）
                        return response.json().then(errData => {
                            // 将错误对象抛出到 catch
                            throw Object.keys(errData).map(key => errData[key])[0][0];
                        });
                    }
                    return response.json();
                })
                .then(result => {
                    // 成功处理
                    row.closest('tr').dataset.id = result.id
                    cancelEdit(row, 'newEdit');
                    showToast('新增用户成功!', 'success');

                    // 1.发送数据给其他tab页同步用:(要发送新增的用户给其他tab页面)
                    // 1-1.更新返回的result与其他页面(权限管理)一样格式
                    const resultUser = updateNewUser(result)
                    // 1-2. 把新增用户加到本地users最前面[0]位置
                    users.unshift(resultUser);
                    // 再刷新页面,保持每页固定显示的条数(默认10条)
                    const keyword = ''
                    const userEl = container.querySelector('#userTypeSelect')
                    const userSelect = userEl ? userEl.value.trim() : 'internal';
                    // loadPage(1, keyword, userSelect, $container)
                    loadPages(1, keyword, userSelect, $container, url, tableLabel)
                    // 1-3. 通知其他tab去同步数据
                    bc.postMessage({
                        type: 'data_updated',
                        payload: {"user_perm_new": resultUser}
                    });
                })
                .catch(error => {
                    // 统一处理错误
                    showToast(error, 'error')
                });
        }

        // 8.保存行编辑
        if (e.target.closest('.save-edit')) {
            const row = e.target.closest('tr');
            const userId = row.dataset.id;
            const data = collectRowData(row);
            fetch(`/acc/users/${userId}/`, {
                method: 'PUT',
                headers: headers,
                body: JSON.stringify(data)
            })
                .then(response => {
                    if (!response.ok) {
                        return response.json().then(err => {
                            throw {
                                status: response.status,
                                message: err.detail || err.username || err.phone || err.email || err.is_staff
                                    || err.is_active || err.groups || err.password || '未知错误'
                            };
                        });
                    }
                    return response.json();
                })
                .then(result => {
                    // 成功逻辑
                    cancelEdit(row, 'newEdit');
                    showToast('成功保存!', 'success');

                    // 发送数据给其他tab页同步用:(所属组改变,权限管理的用户绑定组关系要变化)
                    // 0-0.先提取直接权限
                    const targetUser = users.find(user => parseInt(user.id) === parseInt(userId));
                    const direct_permissions = targetUser ? targetUser.direct_permissions : null;

                    // 0-1.更新返回的result与其他页面(权限管理)一样格式
                    let resultUser = updateNewUser(result)

                    // 0-2 把直接权限和全部权限更新
                    resultUser.direct_permissions = direct_permissions
                    resultUser.permissions.unshift(...direct_permissions)

                    // 1-2. 把更新好的用户替换到本地users相同id的位置
                    users = users.map(user =>
                      parseInt(user.id) === parseInt(resultUser.id) ? resultUser : user
                    );
                    // 1-3. 如果更新的是操作员自己,则更新本地ownUser
                    if(parseInt(resultUser.id) === parseInt(ownID)){
                        ownUser = resultUser
                        ownUser_permissions = getPermissions(ownUser);
                        [isPassword, isEditUser, isDeleteUser, isNewUser] = [
                            '修改密码', '编辑用户', '删除用户', '新增用户'
                        ].map(perm => ownUser_permissions.includes(perm));
                    }

                    // 1-4. 通知其他tab去同步数据
                    bc.postMessage({
                        type: 'data_updated',
                        payload: {"user_perm_edit": resultUser}
                    });

                })
                .catch(error => {
                    // 统一错误处理
                    if (error.status) {
                        // HTTP 错误（如 400、403、500 等）
                        switch (error.status) {
                            case 400:
                                showToast(`${error.message}`, 'error');
                                break;
                            case 403:
                                showToast('无操作权限，请联系管理员', 'error');
                                break;
                            case 404:
                                showToast('用户不存在', 'error');
                                break;
                            default:
                                showToast(`服务器错误 (${error.status})`, 'error');
                        }
                    } else {
                        // 网络错误（如请求未到达服务器）
                        showToast(`出错了:${error}`, 'error');
                    }
                });
        }

        // 9.作废操作
        const target = e.target.closest('button');
        if (!target) return;

        // 10.新建行作废
        if (target.classList.contains('cancel-new')) {
            const row = target.closest('tr');
            row.remove();
        }

        // 11.编辑行作废
        if (target.classList.contains('cancel-edit')) {
            const row = target.closest('tr');
            cancelEdit(row);
        }

        // 12.分页功能
        if (e.target.closest('.pagination-btn')) {
            e.preventDefault();
            paging(e, container, url, tableLabel)
        }

        // 13.分页里的跳转按钮
        if (e.target.closest('#page-jump-btn')) {
            pagingJump(container, url, tableLabel)
        }

        // 14-1 搜索用户名(点击搜索按钮时)
        if (e.target.closest('#searchButton')){
            executeSearch()
        }


    });

    // 监听change事件
    container.addEventListener('change', function (e) {
        if (e.target.closest('#userTypeSelect')) {
            executeSearch()
        }
    })


    // 13-1 回车键跳转支持(
    // )
    $container.on('keypress', '#page-jump-input', function(e) {
        if (e.which === 13) {
            $container.find('#page-jump-btn').trigger('click');
        }
    });

    // 14-2 搜索用户名(输入框回车时)
    $container.on('keypress', '#userSearch', function(e){
        if (e.which === 13) {
          e.preventDefault();
          executeSearch()
        }
    });

    //搜索用户名()
    function executeSearch() {
        const keyw = container.querySelector('#userSearch')
        const keyword = keyw ? keyw.value.trim() : ''
        const userEl = container.querySelector('#userTypeSelect')
        const userSelect = userEl ? userEl.value.trim() : 'internal';
        // loadPage(1, keyword, userSelect, $container)
        loadPages(1, keyword, userSelect, $container, url, tableLabel)
      }

    // 0-1 同步其他tab页面的数据
    function updateLocalData(data){
        // 从[组权分配]过来的数据:
        if(data.groups_perm){
            // 0-1-1 修改本地组及其权限
            groups = data.groups_perm
            // 0-1-2 设置操作员自己的权限
            if (!ownUser_is_superuser) {
                ownUser_permissions = getPermissions(ownUser);
                [isPassword, isEditUser, isDeleteUser, isNewUser] = [
                    '修改密码', '编辑用户', '删除用户', '新增用户'
                ].map(perm => ownUser_permissions.includes(perm));
            }
        }

        //从[权限管理]过来的数据
        if(data.user_group_mgr){
            const index = users.findIndex(user => parseInt(user.id) === parseInt(data.user_group_mgr.id));
            // 替换匹配的用户
            if (index !== -1) {users[index] = data.user_group_mgr; }
            if (parseInt(ownUser.id) === parseInt(data.user_group_mgr.id)) {
                ownUser = data.user_group_mgr;
                ownUser_is_superuser = ownUser.is_superuser
                ownUser_permissions = ownUser.permissions

                isPassword = ownUser_is_superuser ? true : ownUser_permissions.includes('修改密码');
                isEditUser = ownUser_is_superuser ? true : ownUser_permissions.includes('编辑用户');
                isDeleteUser = ownUser_is_superuser ? true : ownUser_permissions.includes('删除用户');
                isNewUser = ownUser_is_superuser ? true : ownUser_permissions.includes('新增用户');
            }
            const useID = data.user_group_mgr.id
            const groupsID = data.user_group_mgr.groups.map(item => item[0]).join(', ');
            // 步骤 1: 获取所有表格行
            const rows = container.querySelectorAll('tr');
            // 步骤 2: 遍历每一行，检查 data-id 是否匹配 useID
            rows.forEach(row => {
              // 获取行的 data-id 属性值
              const rowId = row.getAttribute('data-id');
              if (parseInt(rowId) === parseInt(useID)) {
                // 步骤 3: 在匹配的行内，找到所有 class 包含 "text" 的 span 元素
                const textSpans = row.querySelectorAll('span.text');

                // 步骤 4: 遍历这些 span 元素，替换 data-group-ids 属性
                textSpans.forEach(span => {
                  span.setAttribute('data-group-ids', groupsID);
                });
              }
            });


        }

    }

    // 0-3 权限计算函数
    const getPermissions = (user) => [
        ...new Set([
            ...(user.direct_permissions?.map(d => d[2]) || []),
            ...(user.groups?.flatMap(id =>
                groups.find(g => g.id === id[0])?.permissions?.flatMap(p => p[2] || []) || []
            ) || [])
        ])
    ];


    // 0-2 更新返回result与其他页面(权限管理)一样格式
    function updateNewUser(result){
        // 0. 先取得到result的组id列表,如:[1,2,3...]
        const g = result.groups
        // 1. 用g去匹配groups,得到新用户所属的组:[[id,name],[id,name]...]
        const result_groups = g.map(id => {
          const foundObject = groups.find(item => item.id === id);
          if (foundObject) {
            return [foundObject.id, foundObject.name];
          } else {
            return [];
          }
        });
        // 2.用g去匹配groups里的permissions,得到组权限:['E-Entity', 'E-Entity.parameter', 'E-Entity.parameter.add',...]
        // 3.用g去匹配groups里的permissions,得到组权限名称:['实体管理', '参数管理', '新增参数', '删除参数', '编辑参数', ...]
        // 创建groups的Map优化查找性能
        const groupsMap = new Map(groups.map(g => [g.id, g]));
        const [result_group_permissions, result_permissions] = g.reduce(
          (acc, id) => {
            const matchedObj = groupsMap.get(id);
            if (matchedObj?.permissions?.length > 0) {
              matchedObj.permissions.forEach(perm => {
                // 安全访问（避免越界）
                acc[0].push(perm[1] ?? null);
                acc[1].push(perm[2] ?? null);
              });
            }
            return acc;
          },
           // 初始值：包含两个空数组的数组
            [[],[]]
        );
        // 4.更新返回数据users(result)内容跟权限管理里的users格式一样
        result.direct_permissions = []
        result.groups = result_groups
        result.group_permissions = result_group_permissions
        result.permissions = result_permissions
        result.last_login = ''

        return result
    }

    // 1-1. 新增用户功能
    function addNewRow() {
        // 0. 检查是否已有新增行（通过特定类名标识，如 'new-editing'）
        const existingNewRows = container.querySelectorAll('tr.new-editing');
        if (existingNewRows.length > 0) {
            showToast('已有新增行，请先处理！', 'warning');
            return;
        }
        // 1-1.1 检查其他行是否在编辑
        const editingRows = container.querySelectorAll('tr.table-warning');
        editingRows.forEach(editingRow => {
            const cancelBtn = editingRow.querySelector('.cancel-new, .cancel-edit');
            if (cancelBtn) cancelBtn.click();
        });

        // 1-1.2. 进行新增功能操作
        const tbody = container.querySelector('table tbody');
        // const row = tbody.insertRow(-1); // 在末尾插入新行
        const row = tbody.insertRow(0); // 在最前面插入新行

        // 1-1.2.1 生成下拉菜单HTML(角色权限)
        let dropdownHtml = `
        <div id="groups-multi">
        <span class="text text-sm dropdown-toggle"
            type="text"
            data-bs-toggle="dropdown"
            aria-expanded="false"
            data-group-ids=""
            style="padding: 0">
        ${getSelectedLabels(groups)} <!-- 显示已选项 -->
    </span>

    <ul class="dropdown-menu w-auto min-w-0">`;

        // 1-1.2.2 动态添加多选选项
        groups.forEach(group => {
            dropdownHtml += `
        <li>
            <label class="dropdown-item d-flex align-items-center">
                <input type="checkbox"
                       class="form-check-input me-2"
                       value="${group.id}"
                       ${group.selected ? 'checked' : ''}>
                <span class="text-nowrap">${group.name}</span>
            </label>
        </li>`;
        });

        dropdownHtml += `</ul></div>`;

        // 1-1.2.3 填充可编辑单元格
        row.innerHTML = `
    <td> <!-- 用户名 -->
        <input type="text" class="form-control form-control-sm">
    </td>

    <td> <!-- 手机号 -->
        <input type="tel" class="form-control form-control-sm">
    </td>

    <td> <!-- 邮箱 -->
        <input type="email" class="form-control form-control-sm">
    </td>

    <td> <!-- 员工 -->
        <div class="form-check form-switch">
            <input class="form-check-input" type="checkbox" name="is_staff" id="isStaff" value="true">
        </div>
    </td>

    <td> <!-- 激活 -->
        <div class="form-check form-switch">
            <input class="form-check-input" type="checkbox" name="is_active" id="isActive" value="true">
        </div>
    </td>

    <td>${dropdownHtml}</td> <!-- 角色权限 -->


    <td></td> <!-- 最后登录时间 -->

    <td> <!-- 操作 -->
        <div class="btn-group">
            <button class="btn btn-success btn-sm save-new" title="保存">
                <i class="fas fa-save"></i>
            </button>
            <button class="btn btn-danger btn-sm cancel-new" title="作废">
                <i class="fas fa-times"></i>
            </button>
            <button type="button"
                class="btn btn-sm btn-outline-warning reset-pwd-btn"
                title="重置密码"
                data-userid="{{ user.id }}"
                >
                <i class="fas fa-key"></i>
            </button>
        </div>
    </td>
`;

        // 1-1.2.6 - 2.7 - 2.8
        initMultiDropdown(row);  // 使用函数里的默认配置

        // 1-1.3. 高亮新行和新增状态
        row.classList.add('table-warning', 'new-editing');
    }

    // 1-1.2.2 获取显示标签（如"已选2项"）
    function getSelectedLabels(groups) {
        const selectedCount = groups.filter(g => g.selected).length;
        return selectedCount > 0 ? `已选${selectedCount}项` : '选择角色';
    }

    // 2-1. 行编辑功能
    function enableEdit(row) {
        // 1. 检查其他行是否在编辑
        const editingRows = container.querySelectorAll('tr.table-warning');
        editingRows.forEach(editingRow => {
            if (editingRow !== row) {
                const cancelBtn = editingRow.querySelector('.cancel-new, .cancel-edit');
                if (cancelBtn) cancelBtn.click();
            }
        });

        // 2.进行行编辑-> 2.1 保存原始数据到 dataset（保持原逻辑）
        const cellElements = row.querySelectorAll('td:not(:last-child)');
        row.dataset.original = JSON.stringify(
            Array.from(cellElements).map(cell => cell.textContent.trim())
        );

        // 添加高亮
        row.classList.add('table-warning');
        let aa = 3
        const is_edit = ownUser_permissions.includes('身份角色') ? '' : 'disabled'
        // const is_edit = ownUser_is_superuser ? '' : 'disabled'

        // 转换单元格为可编辑状态
        const cells = row.querySelectorAll('td:not(:last-child)');
        cells.forEach((cell, index) => {
            if (index === aa || index === aa + 1) { // 处理员工,激活,角色权限
                const original = cell.querySelector('.badge').innerText;
                const checked = ['是', '已激活', true].includes(original) ? 'checked' : '';
                let title = ''
                if (index === aa) {
                    title = !!['是', true]
                }
                if (index === aa + 1) {
                    title = !!['已激活', true]
                }

                if (index === aa) {
                    cell.innerHTML = `
                <div class="form-check form-switch">
                    <input class="form-check-input" type="checkbox" name="is_staff" id="isStaff"
                      ${checked} value = ${title}
                      ${is_edit} 
                    >
                </div>
                `;
                }

                if (index === aa + 1) {
                    cell.innerHTML = `
                <div class="form-check form-switch">
                    <input class="form-check-input" type="checkbox" name="is_active" id="isActive"
                      ${checked} value = ${title} 
                      ${is_edit}
                      >
                </div>
                `;
                }

            } else {
                if (index === aa + 2) {
                    // 1. 获取元素
                    const spanElement = cell.querySelector('.text');

                    // 2. 通过 getAttribute 获取原始值
                    const groupIdsString = spanElement.getAttribute('data-group-ids') || '';
                    // 3. 处理并转为数组
                    const groupIds = groupIdsString ? groupIdsString.split(',') : [];
                    // 4. 形成html片段
                    let dropdownHtml = `
            <div id="groups-multi">
                    <span class="text text-sm dropdown-toggle"
                        type="text"
                        data-bs-toggle="dropdown"
                        aria-expanded="false"
                        data-group-ids="${(groupIds) ? (groupIds) : ''}"
                        style="padding: 0">
                     已选${(groupIds).length}项 <!-- 显示已选项 -->
                </span>
                <ul class="dropdown-menu w-auto min-w-0">`;
                    // 4.1 动态添加多选选项
                    groups.forEach(group => {
                        dropdownHtml += `
                    <li>
                        <label class="dropdown-item d-flex align-items-center">
                            <input type="checkbox"
                                   class="form-check-input me-2"
                                   value="${group.id}"
                                   ${groupIds.includes(group.id.toString()) ? 'checked' : ''}
                                   ${is_edit}
                            >
                            <span class="text-nowrap" style="padding: 0">${group.name}</span>
                        </label>
                    </li>`;
                    });

                    dropdownHtml += `</ul></div>`;

                    cell.innerHTML = `<td>${dropdownHtml}</td>`
                    // 5. 调用函数,进行下拉框点击事件等的监控与显示
                    initMultiDropdown(row, {dropdownId: 'groups-multi', textSelector: '.text'});  // 也可用函数里的默认配置

                } else {
                    if (index !== 6) {   // 最后登录时间不用编辑
                        const originalText = cell.innerText;
                        cell.innerHTML = `<input type="text" class="form-control form-control-sm" value="${originalText}">`;
                    }
                }
            }
        });

        // 修改操作按钮
        const actionCell = row.querySelector('td:last-child');
        actionCell.innerHTML = `
        <div class="btn-group">
            <button class="btn btn-success btn-sm save-edit" title="保存">
                <i class="fas fa-save"></i>
            </button>
            <button class="btn btn-danger btn-sm cancel-edit" title="作废">
                <i class="fas fa-times"></i>
            </button>
            <button type="button"
                class="btn btn-sm btn-outline-warning reset-pwd-btn"
                title="重置密码"
                data-userid="{{ user.id }}"
            >
             <i class="fas fa-key"></i>
            </button>
        </div>`;
    }

    // 7.8.-1. 收集信息准备提交后端
    function collectRowData(row) {
        const groupIdsString = row.querySelector('.text').getAttribute('data-group-ids')
        const groupIdList = groupIdsString ? groupIdsString.split(',') : []
        return {
            username: row.querySelector('td:first-child input').value,
            phone: row.querySelector('td:nth-child(2) input').value,
            email: row.querySelector('td:nth-child(3) input').value,
            is_staff: row.querySelector('td:nth-child(4) input').checked,
            is_active: row.querySelector('td:nth-child(5) input').checked,
            groups: groupIdList,
            password: "初始临时密码", // 必须包含密码
            // 其他字段...
        };
    }

    // 获取指定行的groups名称
    function getGroupNames(row) {
        // 处理数据并过滤无效值
        const groupIdsString = row.querySelector('.text').getAttribute('data-group-ids')
        if (groupIdsString === '') return []
        const groupIds = groupIdsString
            .split(',')
            .map(id => Number(id))
        // 使用 map 直接生成名称数组
        return groups.filter(group => groupIds.includes(group.id)).map(group => group.name)

    }

    // 新增保存后,取这一行数据,做为恢复状态用
    function parseTableRow(row) {
        return [
            row.querySelector('td:first-child input').value,      // username 1
            row.querySelector('td:nth-child(2) input').value,     // phone 2
            row.querySelector('td:nth-child(3) input').value,    // email 3
            row.querySelector('td:nth-child(4) input').checked,  // is_staff 4
            row.querySelector('td:nth-child(5) input').checked, // is_active 5
            getGroupNames(row),  // groups 6
            '',  // 最后登录时间 7
            '',  // 操作 8
        ]
    }

    // 作废或保存以后的处理
    function cancelEdit(row, type = '') {
        // 移除高亮
        row.classList.remove('table-warning');
        row.classList.remove('new-editing');   // 新增标记去掉

        const cells = row.querySelectorAll('td:not(:last-child)');
        let aa = 3
        let originalData = ''
        if (type === 'newEdit') {
            // 保存:恢复保存数据
            originalData = parseTableRow(row)
        } else {
            // 作废:恢复原始数据
            originalData = JSON.parse(row.dataset.original);
        }

        cells.forEach((cell, index) => {
            if ([aa, aa + 1].includes(index)) { // 处理开关按钮
                const originalValue = ['是', '已激活', true].includes(originalData[index]) ? 'true' : 'false';
                let originalTitle = ''
                if (index === aa) {
                    originalTitle = ['是', true].includes(originalData[index]) ? '是' : '否';
                }
                if (index === aa + 1) {
                    originalTitle = ['已激活', true].includes(originalData[index]) ? '已激活' : '未激活';
                }
                cell.innerHTML = `
            <span class="badge bg-${originalValue === 'true' ? 'success' : 'danger'}" style="margin: 0">
                ${originalTitle}
            </span>
        `;

            } else {
                if (index === aa + 2) {
                    let uniqueArr = []
                    if (type === 'newEdit') {
                        uniqueArr = originalData[index]   // 新建或真正保存的恢复
                    } else {
                        // 1. 按换行符分割字符串并去除空白字符 (编辑时的作废的恢复)
                        const arr = originalData[index].split('\n').map(s => s.trim()).filter(s => s !== '');
                        // 2. 去重（使用 Set）得到没有乱七八糟的已有权限列表['权限1', '权限2', '权限3'...]
                        uniqueArr = [...new Set(arr)];
                    }
                    // 1. 获取元素id(已有权限列表id)
                    const spanElement = cell.querySelector('.text');
                    // 1.1. 通过 getAttribute 获取原始值
                    const groupIdsString = spanElement.getAttribute('data-group-ids');
                    // 1.2. 处理并转为数组(已有权限列表id)['1', '2', '3'...]
                    const groupIds = groupIdsString ? groupIdsString.split(',') : [];
                    // 4. 形成html片段
                    let dropdownHtml = `
                    <div id="groups-multi">
                        <span class="text text-sm${groupIds.length <= 1 ? '' : ' dropdown-toggle'}"
                              type="text"
                              data-bs-toggle="dropdown"
                              aria-expanded="false"
                              data-group-ids="${(groupIds) ? (groupIds) : ''}"
                              style="padding: 0">
                              ${uniqueArr[0] || '未授权'}
                        </span>
                        <ul class="dropdown-menu w-auto min-w-0">`;
                            // 4.1 动态添加多选选项
                            uniqueArr.forEach(group => {
                                dropdownHtml += `
                            <li>
                                <label class="dropdown-item d-flex align-items-center">
                                    <span class="text-nowrap">${group}</span>
                                </label>
                            </li>`;
                            });

                    dropdownHtml += `</ul></div>`;

                    cell.innerHTML = `<td>${dropdownHtml}</td>`


                } else {
                    cell.innerHTML = originalData[index];
                }
            }
        });

        // 恢复操作按钮
        const actionCell = row.querySelector('td:last-child');
        actionCell.innerHTML = `
        <div class="btn-group">
            <button class="btn btn-sm btn-outline-primary edit-btn" title="编辑">
                <i class="fas fa-edit"></i>
            </button>
            <button class="btn btn-sm btn-outline-danger delete-btn" data-userid="{{ user.id }}" title="删除">
                <i class="fas fa-trash"></i>
            </button>
            <button type="button"
                class="btn btn-sm btn-outline-warning reset-pwd-btn"
                title="重置密码"
                data-userid="{{ user.id }}"
                >
                <i class="fas fa-key"></i>
            </button>
        </div>
    `;
    }

    // 初始化多选下拉菜单事件监听
    function initMultiDropdown(parentElement, options = {}) {
        const config = {
            dropdownId: 'groups-multi',
            textSelector: '.text',
            ...options
        };

        const dropdownDiv = parentElement.querySelector(`#${config.dropdownId}`);
        if (!dropdownDiv.querySelectorAll('input[type="checkbox"]')) return

        // 复选框变化事件
        dropdownDiv.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
            checkbox.addEventListener('change', function () {
                const selectedIds = Array.from(dropdownDiv.querySelectorAll('input:checked'))
                    .map(cb => cb.value)
                    .join(',');

                // 更新 data-group-ids
                const toggleSpan = dropdownDiv.querySelector(config.textSelector);
                if (toggleSpan) {
                    toggleSpan.dataset.groupIds = selectedIds;
                }

                // 更新显示文本
                const selectedCount = selectedIds ? selectedIds.split(',').length : 0;
                // const displayText = selectedCount > 0 ? `已选${selectedCount}项` : '选择角色';
                dropdownDiv.querySelector('.dropdown-toggle').textContent = selectedCount > 0 ? `已选${selectedCount}项` : '选择角色';
            });
        });

        // 阻止点击标签关闭下拉
        const dropdownMenu = dropdownDiv.querySelector('.dropdown-menu');
        if (dropdownMenu) {
            dropdownMenu.addEventListener('click', e => e.stopPropagation());
        }
    }

    // 重置密码模态框(关闭)事件处理
    container.querySelector('#passwordResetModal').addEventListener('hidden.bs.modal', function (event) {
        // 获取存储的高亮行
        const highlightedRow = event.target.currentHighlightRow;
        // 移除高亮样式
        if (highlightedRow) {
            highlightedRow.classList.remove('table-danger');
            // 清理存储的引用
            delete event.target.currentHighlightRow;
        }
        // 清除短信验证表单输入框的内容
        container.querySelector('#smsAuthForm').reset();
        // 清除密码验证表单输入框的内容
        container.querySelector('#passwordForm').reset();
        userId = ''
    });

    // 4-1.送短信验证码
    async function sendSmsCode() {
        const phone = container.querySelector('#phone').value;
        // if (!/^\d{11}$/.test(phone)) return showWarningModal('手机号格式错误');

        try {
            const response = await fetch('/acc/send_sms/', {
                method: 'POST',
                headers,
                body: JSON.stringify({phone, user_id: userId})
            });

            const result = await response.json();

            // response.ok ?
            result.success ? showToast('验证码已发送', 'info') : showToast(result.error, 'error');

        } catch (error) {
            showToast('短信发送失败:' + error, 'error');
        }
    }

    // 统一提交处理函数
    async function handleAuthSubmit(formType, data) {
        const payload = {
            auth_method: formType,
            ...data
        };

        try {
            const response = await fetch('/acc/password/reset/', {
                method: 'POST',
                headers,
                body: JSON.stringify(payload)
            });

            const result = await response.json();

            if (response.ok) {
                showToast('已成功更换成新密码了', 'success')
                // 同时关闭模态框和遮罩层
                $('#passwordResetModal').modal('hide')

            } else {
                if (result.error) {
                    showToast(result.error, 'error')
                } else {
                    showToast('验证失败', 'error')
                }
            }
        } catch (error) {
            showToast(error.message, 'error');
        }
    }

    // 短信sms验证提交监听
    container.querySelector('#smsAuthForm').addEventListener('submit', async (e) => {
        e.preventDefault();
        const phone = container.querySelector('#phone').value.trim();
        const smsCode = container.querySelector('#smsCode').value.trim();
        const newPassword = container.querySelector('#smsNewPassword').value.trim();
        const confirmPassword = container.querySelector('#smsConfirmPassword').value.trim();

        if (newPassword.length < 6) {
            return showToast("新密码至少6位", 'warning')
        }
        if (confirmPassword < 6) {
            return showToast("确认密码至少6位", 'warning')
        }
        if (newPassword !== confirmPassword) {
            return showToast("新密码与确认密码不一致", 'warning')
        }

        if (!/^\d{11}$/.test(phone)) {
            return showToast('手机号格式错误', 'warning');
        }

        if (smsCode.length !== 6) {
            return showToast('验证码必须为6位', 'warning');
        }

        await handleAuthSubmit('sms', {
            phone,
            sms_code: smsCode,
            new_password: newPassword,
            confirm_password: confirmPassword,
            user_id: userId
        });
    });

    // 重置密码提交
    container.querySelector('#passwordForm').addEventListener('submit', async (e) => {
        e.preventDefault();
        const oldPassword = container.querySelector('#oldPassword').value.trim();
        const newPassword = container.querySelector('#newPassword').value.trim();
        const confirmPassword = container.querySelector('#confirmPassword').value.trim();

        if (oldPassword.length < 6) {
            return showToast("原密码至少6位", 'warning')
        }
        if (newPassword.length < 6) {
            return showToast("新密码至少6位", 'warning')
        }
        if (confirmPassword < 6) {
            return showToast("确认密码至少6位", 'warning')
        }
        if (newPassword !== confirmPassword) {
            return showToast("新密码与确认密码不一致", 'warning')
        }
        if (oldPassword === confirmPassword) {
            return showToast("新密码不能和原密码一样", 'warning')
        }
        await handleAuthSubmit('newPassword',
            {
                old_password: oldPassword,
                new_password: newPassword,
                confirm_password: confirmPassword,
                user_id: userId
            });
    });

    // 4-1.密码明文与密文
    function togglePassword(fieldId, buttonElement) {
        // 1. 获取密码输入框
        const passwordField = container.querySelector(`#${fieldId}`);

        // 2. 切换密码可见性
        const isPasswordVisible = passwordField.type === 'text';
        passwordField.type = isPasswordVisible ? 'password' : 'text';

        // 3. 切换按钮图标（通过传递的 buttonElement 操作子元素）
        const icon = buttonElement.querySelector('i');
        icon.classList.toggle('fa-eye');       // 切换睁眼图标
        icon.classList.toggle('fa-eye-slash'); // 切换闭眼图标
    }

}
})();